/**
 * 
 */
package idv.takeshi.software.productline.bookstore.presentation.dto;

import java.util.Date;

import idv.takeshi.software.productline.bookstore.domain.model.useraccount.IndividualAccount;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.Sex;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.UserAccountFactory;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;

import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;

/**
 * A data-transfer Object for IndividualAccount model.
 * @author takeshi
 *
 */
public class IndividualAccountDto extends UserAccountDto<IndividualAccount> {
	
	@Pattern(regexp = ".+")
	@NotNull
	private String lastName;
	@Pattern(regexp = ".+")
	@NotNull
	private String firstName;
	
	@Pattern(regexp = "(MALE|FEMALE)")
	@NotNull
	private String sex;
	
	@Past
	@NotNull
	@DateTimeFormat(iso=ISO.DATE)
	private Date birthday;
	
	/**
	 * @return the lastName
	 */
	public String getLastName() {
		return lastName;
	}
	/**
	 * @param lastName the lastName to set
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	/**
	 * @return the firstName
	 */
	public String getFirstName() {
		return firstName;
	}
	/**
	 * @param firstName the firstName to set
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	/**
	 * @return the sex
	 */
	public String getSex() {
		return sex;
	}
	/**
	 * @param sex the sex to set
	 */
	public void setSex(String sex) {
		this.sex = sex;
	}
	/**
	 * @return the birthday
	 */
	public Date getBirthday() {
		return birthday;
	}
	/**
	 * @param birthday the birthday to set
	 */
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.presentation.dto.UserAccountDto#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == null) { return false; }
		   if (obj == this) { return true; }
		   if (obj.getClass() != getClass()) {
		     return false;
		   }
		   IndividualAccountDto rhs = (IndividualAccountDto) obj;
		   return new EqualsBuilder()
		   	   .appendSuper(super.equals(rhs))
			   .append(this.lastName, rhs.lastName)
			   .append(this.firstName, rhs.firstName)
			   .append(this.sex, rhs.sex)
			   .append(this.birthday, rhs.birthday)
		       .isEquals();
	}
	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.presentation.dto.UserAccountDto#hashCode()
	 */
	@Override
	public int hashCode() {
		return new HashCodeBuilder(37, 41).
		   appendSuper(super.hashCode()).
	       append(this.lastName).
	       append(this.firstName).
	       append(this.sex).
	       append(this.birthday).
	       toHashCode();
	}
	
	
	
	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.presentation.dto.UserAccountDto#createModel(idv.takeshi.software.productline.bookstore.domain.model.useraccount.UserAccountFactory)
	 */
	@Override
	public IndividualAccount createModel(UserAccountFactory userAccountFactory){
		Validate.notNull(userAccountFactory, "userAccountFactory shall always not be null");
		IndividualAccount account = userAccountFactory.newInstance(IndividualAccount.class, this.getAccountName());
		
		account.setOriginalPassword(this.getPassword());
		account.setZipCode(this.getZipCode());
		account.setContactAddress(this.getContactAddress());
		account.setContactPhoneNumber(this.getContactPhoneNumber());
		account.setCellPhoneNumber(this.getCellPhoneNumber());
		account.setEmailAddress(this.getEmailAddress());
		account.setLastName(this.getLastName());
		account.setFirstName(this.getFirstName());
		account.setSex(Sex.valueOf(this.getSex()));
		account.setBirthday(this.getBirthday());
		
		return account;
	}

}
